package com.gjy.concurrency.h1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-05-30 14:29:08
 */
public class PoolInfo {

    private static final Logger logger = LoggerFactory.getLogger(PoolTest.class);
    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

    public static void main(String[] args) {

        String corn = "0/5 * * * * ?";
        CronTrigger cronTrigger = new CronTrigger(corn);

        SimpleTriggerContext context = new SimpleTriggerContext();
        Date date = cronTrigger.nextExecutionTime(context);

        logger.info("now  = {}", FORMAT.format(new Date()));
        logger.info("date = {}", FORMAT.format(date));

        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.initialize();

        scheduler.schedule(() -> {
            logger.info("{}", FORMAT.format(new Date()));
        }, cronTrigger);

    }

    private static void corn1() {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        Runnable task = () -> System.out.println("Task executed at " + new Date());

        // 每天的11点30分执行任务
        String cronExpr = "* * * * * *";
        CronTrigger cronTrigger = new CronTrigger(cronExpr);
/*
        scheduledExecutorService.schedule(task,
                Objects.requireNonNull(cronTrigger.nextExecutionTime(new SimpleTriggerContext())).getTime() - System.currentTimeMillis(),
                TimeUnit.MILLISECONDS);
*/
        scheduledExecutorService.scheduleWithFixedDelay(task,
                Objects.requireNonNull(cronTrigger.nextExecutionTime(new SimpleTriggerContext())).getTime() - System.currentTimeMillis(),
                3,
                TimeUnit.SECONDS);
    }

    private static void timer() {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Task executed at " + new Date());
            }
        };

        // 每天的11点30分执行任务
        timer.schedule(task, getFirstTime(), 24 * 60 * 60 * 1000);
    }

    private static Date getFirstTime() {
        // 获取当前时间
        Date now = new Date();
        // 设定执行时间为每天11点30分
        Date firstTime = new Date();
        firstTime.setHours(14);
        firstTime.setMinutes(50);
        firstTime.setSeconds(0);
        // 如果当前时间已经超过执行时间，则将执行时间改为明天的执行时间
        if (now.after(firstTime)) {
            long interval = 24 * 60 * 60 * 1000;
            firstTime = new Date(firstTime.getTime() + interval);
        }
        return firstTime;
    }

    private static void schedule() {
        int processors = Runtime.getRuntime().availableProcessors();
        ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(processors);

        /*pool.scheduleWithFixedDelay(() -> {
            try {
                System.out.println(LocalDateTime.now());
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, 3, 2, TimeUnit.SECONDS);

        System.out.println(LocalDateTime.now());*/
        scheduleAtFixedRate(pool);
    }

    private static void scheduleAtFixedRate(ScheduledThreadPoolExecutor pool) {
        pool.scheduleAtFixedRate(() -> {
            try {
                System.out.println(LocalDateTime.now());
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, 3, 2, TimeUnit.SECONDS);

        System.out.println(LocalDateTime.now());

        /*
        2023-05-30T14:38:37.441
        2023-05-30T14:38:40.428
        2023-05-30T14:38:42.424
        2023-05-30T14:38:44.425
        2023-05-30T14:38:46.426
        2023-05-30T14:38:48.431
        * */
    }
}
